{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2022-11-01 10:06:07.633630: I tensorflow/core/util/util.cc:169] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
      "2022-11-01 10:06:07.637436: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
      "2022-11-01 10:06:07.637449: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n",
      "2022-11-01 10:06:08.933126: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory\n",
      "2022-11-01 10:06:08.933151: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)\n",
      "2022-11-01 10:06:08.933164: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (mpc-empty011122134151.ea134): /proc/driver/nvidia/version does not exist\n",
      "2022-11-01 10:06:08.933390: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F AVX512_VNNI FMA\n",
      "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "\n",
    "import tf_encrypted as tfe\n",
    "from tf_encrypted.keras.losses import BinaryCrossentropy\n",
    "from tf_encrypted.keras.optimizers import SGD\n",
    "from tf_encrypted.player import DataOwner\n",
    "from tf_encrypted.keras.datasets import LogisticArtificialDataset\n",
    "\n",
    "config = tfe.get_config()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "batch_size = 100\n",
    "epochs = 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_dataset = LogisticArtificialDataset(batch_size=batch_size)\n",
    "test_dataset = LogisticArtificialDataset(batch_size=batch_size, train=False)\n",
    "train_client = DataOwner(config.get_player(\"train-client\"), train_dataset.generator_builder())\n",
    "test_client = DataOwner(config.get_player(\"test-client\"), test_dataset.generator_builder())\n",
    "\n",
    "train_iter = train_client.provide_data()\n",
    "test_iter = test_client.provide_data()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Define Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = tfe.keras.Sequential()\n",
    "model.add(tfe.keras.layers.Dense(1, batch_input_shape=[batch_size, train_dataset.num_features]))\n",
    "model.add(tfe.keras.layers.Activation('sigmoid'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/20\n",
      "20/20 [==============================] - 11s 5ms/step - loss: 0.5789 - time: 0.5322\n",
      "Epoch 2/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.5473 - time: 0.0035\n",
      "Epoch 3/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.5204 - time: 0.0033\n",
      "Epoch 4/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.4974 - time: 0.0034\n",
      "Epoch 5/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.4777 - time: 0.0031\n",
      "Epoch 6/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.4605 - time: 0.0033\n",
      "Epoch 7/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.4456 - time: 0.0032\n",
      "Epoch 8/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.4324 - time: 0.0034\n",
      "Epoch 9/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.4205 - time: 0.0034\n",
      "Epoch 10/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.4099 - time: 0.0035\n",
      "Epoch 11/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.4002 - time: 0.0034\n",
      "Epoch 12/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.3914 - time: 0.0033\n",
      "Epoch 13/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.3832 - time: 0.0036\n",
      "Epoch 14/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.3757 - time: 0.0036\n",
      "Epoch 15/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.3686 - time: 0.0035\n",
      "Epoch 16/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.3621 - time: 0.0035\n",
      "Epoch 17/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.3559 - time: 0.0036\n",
      "Epoch 18/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.3501 - time: 0.0034\n",
      "Epoch 19/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.3447 - time: 0.0033\n",
      "Epoch 20/20\n",
      "20/20 [==============================] - 0s 5ms/step - loss: 0.3396 - time: 0.0036\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'binary_accuracy': <tf.Tensor: shape=(), dtype=float32, numpy=0.98>}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.compile(optimizer=SGD(learning_rate=1), loss=BinaryCrossentropy())\n",
    "\n",
    "# Train\n",
    "model.fit(x=train_iter, epochs=epochs, steps_per_epoch=train_dataset.iterations)\n",
    "\n",
    "# evaluate\n",
    "model.evaluate(x=test_iter, metrics=[\"binary_accuracy\"], steps=None)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.8.13 ('tfe2')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.13"
  },
  "vscode": {
   "interpreter": {
    "hash": "2b3cf1a821f25a2bafd97d4b4f3a77d0e1f42d8d78c0e512d3a72b703c70416e"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
